﻿/*
Copyright (c) 2009 Vratislav Cermak (vratacermak@gmail.com)
 
This file is part of TeachMe Project. See http://code.google.com/p/teach-me for more information.
 
TeachMe is an open source project. Using of TeachMe is free of charge.
It is distributed under GNU General Public License version 3 (GPLv3).
GPLv3 can be found at http://www.gnu.org/licenses/gpl.html.
 
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the license for more details.
*/

using System;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using TeachMe.Application.Controls;

namespace TeachMe.Application.Configuration
{
    public class Hotkey
    {
        private string _value;

        [XmlElement("Value")]
        public string XmlValue
        {
            get
            {
                return _value;
            }
            set
            {
                _value = value;
            }
        }

        [XmlAttribute(AttributeName = "type")]
        public HotkeyType Type { get; set; }

        public Keys? Get()
        {
            Keys modifiers, key;
            if (Get(out modifiers, out key))
            {
                return (modifiers | key);
            }
            return null;
        }

        public bool Get(out Keys modifiers, out Keys key)
        {
            return TryParseHotkey(_value, out modifiers, out key);
        }

        public void Set(Keys modifiers, Keys key)
        {
            _value = TransformHotkey(modifiers, key);
        }

        public void Clear()
        {
            _value = String.Empty;
        }

        private static bool TryParseHotkey(string value, out Keys modifiers, out Keys key)
        {
            modifiers = Keys.None;
            key = Keys.None;

            if (String.IsNullOrEmpty(value))
            {
                return false;
            }

            string[] items = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);

            if (items.Length < 2)
            {
                return false;
            }

            try
            {
                key = (Keys)Enum.Parse(typeof(Keys), items[items.Length - 1].Trim());
            }
            catch (ArgumentException)
            {
                return false;
            }

            try
            {
                for (int idx = 0; idx < items.Length - 1; idx++)
                {
                    modifiers |= (Keys)Enum.Parse(typeof(Keys), items[idx].Trim());
                }
            }
            catch (ArgumentException)
            {
                return false;
            }

            return true;
        }

        private static string TransformHotkey(Keys modifiers, Keys key)
        {
            StringBuilder result = new StringBuilder();

            if ((modifiers & Keys.Control) == Keys.Control)
            {
                result.Append(Keys.Control);
            }
            if ((modifiers & Keys.Alt) == Keys.Alt)
            {
                if (result.Length > 0)
                {
                    result.Append(", ");
                }
                result.Append(Keys.Alt);
            }
            if ((modifiers & Keys.Shift) == Keys.Shift)
            {
                if (result.Length > 0)
                {
                    result.Append(", ");
                }
                result.Append(Keys.Shift);
            }
            if ((modifiers & Keys.LWin) == Keys.LWin || (modifiers & Keys.RWin) == Keys.RWin)
            {
                if (result.Length > 0)
                {
                    result.Append(", ");
                }
                result.Append(Keys.LWin);
            }
            result.Append(", ");
            result.Append(key);

            return result.ToString();
        }

        public string Translate()
        {
            Keys modifiers, key;
            if (Get(out modifiers, out key)) 
            {
                return HotkeyEdit.Translate(modifiers, key);
            }
            return String.Empty;
        }
    }
}
